from pexpect import spawn,ExceptionPexpect,EOF,TIMEOUT

def sync(tmpfile, remote_file, password):
    cmd = 'scp -q -o"port=36000" %s %s' % (tmpfile, remote_file)
    #cmd = 'rsync -azW %s %s' % (tmpfile, remote_file)    
    handle = spawn(cmd)
    events = ["(?i)are you sure you want to continue connecting", 
              "(?i)(?:password)|(?:passphrase for key)", 
              "(?i)permission denied", 
              "(?i)connection closed by remote host", 
              EOF, 
              TIMEOUT]
    i = handle.expect(events, timeout=2)

    # First phase
    if i==0: 
        # New certificate -- always accept it.
        # This is what you get if SSH does not have the remote host's
        # public key stored in the 'known_hosts' cache.
        handle.sendline("yes")
        i = handle.expect(events)
    if i==1: # password or passphrase
        handle.sendline(password)
        i = handle.expect(events)
        
    # Second phase
    if i==1: # password prompt again
        # For incorrect passwords, some ssh servers will
        # ask for the password again, others return 'denied' right away.
        # If we get the password prompt again then this means
        # we didn't get the password right the first time. 
        handle.close()
        raise ExceptionPexpect ('password refused')
    elif i==2: # permission denied -- password was bad.
        handle.close()
        raise ExceptionPexpect ('permission denied')
    elif i==3: # Connection closed by remote host
        handle.close()
        raise ExceptionPexpect ('connection closed')
    elif i==4: # received EOF
        output = handle.before
        handle.close()
        return output
    elif i==5: # Timeout
        #This is tricky... I presume that we are at the command-line prompt.
        #It may be that the shell prompt was so weird that we couldn't match
        #it. Or it may be that we couldn't log in for some other reason. I
        #can't be sure, but it's safe to guess that we did login because if
        #I presume wrong and we are not logged in then this should be caught
        #later when I try to set the shell prompt.
        pass
    else: # Unexpected 
        handle.close()
        raise ExceptionPexpect ('unexpected login response')

